package xj.graph2d.app.prop;

import static xj.graph2d.app.resources.Resources.getResourceString;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JToggleButton;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import xj.graph2d.Command;
import xj.graph2d.DrawAttr;
import xj.graph2d.DrawCanvas;
import xj.graph2d.DrawShape;
import xj.graph2d.SimpleDrawDocument;
import xj.graph2d.SimpleDrawView;
import xj.graph2d.app.DrawApp;
import xj.graph2d.command.SetAttrCommand;
import xj.graph2d.dialog.OptionDialogPanel;
import xj.util.gui.ColoredSquare;

public class GradientListener 
  extends AttrListener 
  implements ActionListener {

  public GradientListener() {
  }

  public GradientListener(FillIcon fillIcon) {
    this.fillIcon = fillIcon;
  }

  @Override
  protected void init() {
    Object ic = DrawApp.getIcon("fillIcon");
    if (ic instanceof FillIcon) {
      fillIcon = (FillIcon) ic;
    }
  }

  public void setFillIcon(FillIcon fillIcon) {
    this.fillIcon = fillIcon;
  }

  public void setAttr(boolean filled, DrawAttr attr) {    
    this.filled = filled;
    this.attr = attr;
  }

  public void actionPerformed(ActionEvent e) {
    //System.out.println("GradientListener");
    //if (source == null) { 

    if (gradientPanel == null) { 
      gradientPanel = new GradientPanel(main, getResourceString("GradientDialog.title"));
    }
    gradientPanel.setOption();
    gradientPanel.showOptionDialog();

    AbstractButton comp = null;
    if (source instanceof AbstractButton) {
      comp = (AbstractButton) source;
      comp.repaint();
    }
  }

  GradientPanel gradientPanel = null; 

  FillIcon fillIcon = null;
  boolean filled = false; 
  DrawAttr attr = null;;

  class GradientPanel 
    extends OptionDialogPanel
    implements ChangeListener {
    
    GradientPanel(DrawApp main, String title) { 
      super(main.getJFrame(), 
	    JOptionPane.OK_CANCEL_OPTION, title);
      this.main = main;
      
      setLayout(new BorderLayout());
      //setBorder(BorderFactory.createEtchedBorder());    
      
      topPanel = new JPanel(new BorderLayout());
      add(topPanel, BorderLayout.NORTH);
      
      leftPanel = new JPanel();
      leftPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
      leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
      fillCheckbox = new JCheckBox(getResourceString("Gradient.Fill.text"));    
      solidButton = new JRadioButton(getResourceString("Gradient.Solid.text")); 
      linearButton = new JRadioButton(getResourceString("Gradient.Linear.text")); 
      radialButton = new JRadioButton(getResourceString("Gradient.Radial.text")); 
      ButtonGroup group = new ButtonGroup();
      group.add(solidButton);
      group.add(linearButton);
      group.add(radialButton);
      
      JPanel line = new JPanel();    
      line.setLayout(new BoxLayout(line, BoxLayout.X_AXIS));
      line.add(fillCheckbox);
      line.add(Box.createHorizontalGlue());
      leftPanel.add(line);
      
      line = new JPanel();
      line.setLayout(new BoxLayout(line, BoxLayout.X_AXIS));
      line.add(Box.createRigidArea(new Dimension(10, 0)));
      line.add(solidButton);
      line.add(Box.createHorizontalGlue());
      leftPanel.add(line);
      
      line = new JPanel();
      line.setLayout(new BoxLayout(line, BoxLayout.X_AXIS));
      line.add(Box.createRigidArea(new Dimension(10, 0)));
      line.add(linearButton);
      line.add(Box.createHorizontalGlue());
      leftPanel.add(line);
      
      line = new JPanel();
      line.setLayout(new BoxLayout(line, BoxLayout.X_AXIS));
      line.add(Box.createRigidArea(new Dimension(10, 0)));
      line.add(radialButton);
      line.add(Box.createHorizontalGlue());
      leftPanel.add(line);
      leftPanel.add(Box.createVerticalGlue());
      topPanel.add(leftPanel,   BorderLayout.WEST);
      
      ActionListener gl = new ActionListener() { 
	  public void actionPerformed(ActionEvent e) { 
	    Object source = e.getSource();
	    if (source instanceof GradientButton) {
	      GradientButton gb = (GradientButton) source;
	      DrawAttr attr = previewPanel.getDrawAttr();
	      attr.setGradientMode(gb.attr.getGradientMode());
	      attr.setGradientReflect(gb.attr.isGradientReflect());
	      previewPanel.updatePreview();
	    }
	  }
	};
      
      previewPanel = new PreviewPanel();
      //add(previewPanel, BorderLayout.SOUTH);
      add(previewPanel, BorderLayout.CENTER);
      
      colorPanel = new JPanel();
      /*
      colorPanelBorder = BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "",
							  TitledBorder.LEFT, TitledBorder.TOP,
							  titleFont, Color.BLACK);; 
      */

      colorPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
      //colorPanel.setBorder(BorderFactory.createEtchedBorder());
      colorPanelLabel = new JLabel();
      colorPanelLabel.setHorizontalAlignment(SwingConstants.LEFT);
      colorPanelLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
      colorPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
      colorPanel.setLayout(new BoxLayout(colorPanel, BoxLayout.X_AXIS));  
      colorIcon1 = new ColoredSquare(color1, 25, 25);
      colorButton1 = new JButton(colorIcon1);
      colorButton1.setAlignmentY(Component.CENTER_ALIGNMENT);
      colorPanel.add(colorButton1);
      
      colorPanel.add(Box.createRigidArea(new Dimension(10, 30)));
      swapButton = new JButton(DrawApp.getIcon("flipHorizontalIcon")); 
      swapButton.setAlignmentY(Component.CENTER_ALIGNMENT);
      colorPanel.add(swapButton);
      colorPanel.add(Box.createRigidArea(new Dimension(10, 30)));
      
      colorIcon2 = new ColoredSquare(color2, 25, 25);
      colorButton2 = new JButton(colorIcon2);
      colorButton2.setAlignmentY(Component.CENTER_ALIGNMENT);
      colorPanel.add(colorButton2);
      colorPanel.add(Box.createHorizontalGlue());    
      
      transPanel = new TransparencyPanel();
      transPanel.addChangeListener(this);
      topPanel.add(transPanel, BorderLayout.SOUTH);
      
      
      centerPanel = new JPanel();
      centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));
      centerPanel.add(colorPanelLabel);
      centerPanel.add(Box.createVerticalStrut(3));
      centerPanel.add(colorPanel);
      centerPanel.add(Box.createVerticalStrut(3));
      
      gradientPanels[0] = new GPanel();
      gradientPanels[1] = new LinearGradientPanel(gl);
      gradientPanels[2] = new RadialGradientPanel(gl);
      
      middlePanel = new JPanel(centerPanelLayout = new CardLayout());
      /*
      middlePanelBorder = BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "",
							   TitledBorder.LEFT, TitledBorder.TOP,
							   titleFont, Color.BLACK);; 
      */
      middlePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
      //middlePanel.setBorder(BorderFactory.createEtchedBorder());
      middlePanelLabel = new JLabel();
      middlePanelLabel.setHorizontalAlignment(SwingConstants.LEFT);
      middlePanelLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
      middlePanel.setAlignmentX(Component.LEFT_ALIGNMENT);
      middlePanel.add(gradientPanels[0], "solid");
      middlePanel.add(gradientPanels[1], "linear");
      middlePanel.add(gradientPanels[2], "radial");
      centerPanel.add(middlePanelLabel);
      centerPanel.add(Box.createVerticalStrut(3));
      centerPanel.add(middlePanel);
      centerPanel.add(Box.createVerticalStrut(3));
      
      topPanel.add(centerPanel, BorderLayout.CENTER);   
      
      fillCheckbox.setSelected(false); 
      solidButton.setSelected(true);
      solidButton.setEnabled(false);
      linearButton.setSelected(false);
      linearButton.setEnabled(false);
      radialButton.setSelected(false);
      radialButton.setEnabled(false);
      curState = NO_FILL;
      centerPanelLayout.show(middlePanel, "solid");
      colorButton1.setVisible(false);
      colorButton2.setVisible(false);
      swapButton.setVisible(false);
      transPanel.setVisible(false);
      
      ActionListener al = new ActionListener() { 
	  public void actionPerformed(ActionEvent e) { 
	    Object source = e.getSource();
	    ColoredSquare icon = null;
	    JButton button = null;
	    if (source == colorButton1) {
	      icon = colorIcon1;
	      button = colorButton1; 
	    } else if (source == colorButton2) {
	      icon = colorIcon2;
	      button = colorButton2; 
	    }
	    if (icon != null) { 
	      Color selectedColor = JColorChooser.showDialog(null,  
							     getResourceString("ColorChooser.title"),
							     icon.getColor());
	      if (selectedColor != null) { 
		icon.setColor(selectedColor);
		button.repaint();
		
		DrawAttr attr = previewPanel.getDrawAttr();
		attr.setFillColor(colorIcon1.getColor());
		if (!solidButton.isSelected()) { 
		  attr.setGradientColor1(colorIcon1.getColor());
		  attr.setGradientColor2(colorIcon2.getColor());
		}
		previewPanel.updatePreview();
		updateGradientPanels();
	      }
	    }
	  }
	};
      colorButton1.addActionListener(al);
      colorButton2.addActionListener(al);
      
      ActionListener sl = new ActionListener() { 
	  public void actionPerformed(ActionEvent e) { 
	    Color c1 = colorIcon1.getColor();
	    Color c2 = colorIcon2.getColor();
	    colorIcon1.setColor(c2);
	    colorIcon2.setColor(c1);
	    colorButton1.repaint(); 
	    colorButton2.repaint(); 
	    DrawAttr attr = previewPanel.getDrawAttr();
	    attr.setFillColor(c2);
	    if (!solidButton.isSelected()) { 
	      attr.setGradientColor1(c2);
	      attr.setGradientColor2(c1);
	    }
	    previewPanel.updatePreview();
	    updateGradientPanels();
	  }
	};
      swapButton.addActionListener(sl);

      ChangeListener cl = new ChangeListener() { 
	  public void stateChanged(ChangeEvent e) {
	    //System.out.println("fillCheckbox: " + fillCheckbox.isSelected());
	    int s = getState();
	    if (s != curState) { 
	      
	      if (attr != null) { 
		Color c0 = attr.getFillColor();
		Color c1 = attr.getGradientColor1();
		Color c2 = attr.getGradientColor2();
		if (s == FILL_SOLID) {
		  if (c0 == null) { 
		    c0 = DrawAttr.defaultFillColor;
		  }
		  colorIcon1.setColor(c0);
		} else if (s == FILL_LINEAR_GRADIENT || 
			   s == FILL_RADIAL_GRADIENT) { 
		  if (c1 == null) { 
		    c1 = color1;
		  }
		  if (c2 == null) { 
		    c2 = color2;
		  }
		  colorIcon1.setColor(c1);
		  colorIcon2.setColor(c2);
		}
	      }
	      
	      updatePanels();
	      curState = s; 
	    }
	  }	
	};
      
      fillCheckbox.addChangeListener(cl);
      solidButton.addChangeListener(cl);
      linearButton.addChangeListener(cl);
      radialButton.addChangeListener(cl);
      
      setPreferredSize(new Dimension(350, 300));
    }
    
    // method for ChangeListener of TransparencyPanel
    public void stateChanged(ChangeEvent e) {
      updatePanels();
    }
    
    public void setOption() {
      if (updateSystemAttr) {
	SimpleDrawView view = main.getView();
	attr = view.getDrawAttr();
	setAttr(attr);
      } else { 
	setAttr(filled, attr);
      }
    }

    public void setAttr(boolean filled, DrawAttr attr) { 
      fillCheckbox.setSelected(filled);
      setAttr(attr); 
    }
    
    public void setAttr(DrawAttr attr) { 
      if (attr != null) { 
	Color c0 = attr.getFillColor();
	Color c1 = attr.getGradientColor1();
	Color c2 = attr.getGradientColor2();
	boolean solid = (c1 == null && c2 == null);
	DrawAttr pattr = previewPanel.getDrawAttr();
	pattr.setFillColor(c0);
	pattr.setGradientColor1(c1);
	pattr.setGradientColor2(c2);
	pattr.setGradientMode(attr.getGradientMode());
	pattr.setGradientReflect(attr.isGradientReflect());
	if (solid) {
	  solidButton.setSelected(true);
	  colorIcon1.setColor(c0);
	} else { 
	  if (attr.isLinearGradientMode()) { 
	    linearButton.setSelected(true);
	  } else { 
	    radialButton.setSelected(true);
	  }
	  colorIcon1.setColor(c1);
	  colorIcon2.setColor(c2);
	}
	updatePanels();
      }
    }
    
    @Override
	public void applyOptions() {
      boolean filled = updateSystemAttr || fillCheckbox.isSelected();
      Color color1 = colorIcon1.getColor();
      Color color2 = colorIcon2.getColor();
      int a = transPanel.getValue();
      if (a < 255) {
	color1 = new Color(color1.getRed(), color1.getGreen(), color1.getBlue(), a);
	color2 = new Color(color2.getRed(), color2.getGreen(), color2.getBlue(), a);
      }

      if (fillIcon != null) { 
	DrawAttr fillIconAttr = fillIcon.getDrawAttr();
	DrawShape fillIconShape = fillIcon.getDrawShape();
	fillIconShape.setFilled(filled); 
	if (fillIconAttr != null) { 	  
	  fillIconAttr.setFillColor(color1);
	  if (solidButton.isSelected()) { 
	    fillIconAttr.setGradientColor1(null);
	    fillIconAttr.setGradientColor2(null);
	  } else { 
	    fillIconAttr.setGradientColor1(color1);
	    fillIconAttr.setGradientColor2(color2);
	    fillIconAttr.setGradientMode(previewPanel.getDrawAttr().getGradientMode());
	    fillIconAttr.setGradientReflect(previewPanel.getDrawAttr().isGradientReflect());
	  }
	}
      }

      SimpleDrawDocument doc = main.getDoc();
      SimpleDrawView view = main.getView();
      DrawAttr attr = view.getDrawAttr();
      if (updateSystemAttr &&
	  attr != null) {
	// update system attribute
	attr.setFillColor(color1);
	if (solidButton.isSelected()) { 
	  attr.setGradientColor1(null);
	  attr.setGradientColor2(null);
	} else { 
	  attr.setGradientColor1(color1);
	  attr.setGradientColor2(color2);
	  attr.setGradientMode(previewPanel.getDrawAttr().getGradientMode());
	  attr.setGradientReflect(previewPanel.getDrawAttr().isGradientReflect());
	}
      }
      
      // update current shape
      if (doc != null) {
	DrawShape curShape = doc.getSelectedShape();
	if (curShape != null) {
	  curShape.setFilled(filled);
	  DrawAttr curAttr = curShape.getDrawAttr();
	  if (curAttr != null) { 
	    Command cmd = new SetAttrCommand(view, doc, curShape);
	    doc.addCommand(cmd);
	    
	    curAttr.setFillColor(color1);
	    if (solidButton.isSelected()) { 
	      curAttr.setGradientColor1(null);
	      curAttr.setGradientColor2(null);
	    } else { 
	      curAttr.setGradientColor1(color1);
	      curAttr.setGradientColor2(color2);
	      curAttr.setGradientMode(previewPanel.getDrawAttr().getGradientMode());
	      curAttr.setGradientReflect(previewPanel.getDrawAttr().isGradientReflect());
	    }	  
	    
	    DrawCanvas canvas = view.getCanvas();
	    canvas.repaintShape(curShape);
	  }
	}
      }
    }

    protected int getState() {
      if (fillCheckbox.isSelected()) { 
	if (solidButton.isSelected()) { 
	  return FILL_SOLID;
	} else if (linearButton.isSelected()) { 
	  return FILL_LINEAR_GRADIENT;
	} else { 
	  return FILL_RADIAL_GRADIENT;
	}
      } else { 
	return NO_FILL; 
      }
    }

    protected void updatePanels() { 
      DrawShape previewShape = previewPanel.getDrawShape();
      DrawAttr attr = previewPanel.getDrawAttr();
      Color color1 = colorIcon1.getColor();
      Color color2 = colorIcon2.getColor();
      int a = transPanel.getValue();
      if (a < 255) {
	color1 = new Color(color1.getRed(), color1.getGreen(), color1.getBlue(), a);
	color2 = new Color(color2.getRed(), color2.getGreen(), color2.getBlue(), a);
      }
      attr.setFillColor(color1);
      if (solidButton.isSelected()) { 
	attr.setGradientColor1(null);
	attr.setGradientColor2(null);
      } else { 
	attr.setGradientColor1(color1);
	attr.setGradientColor2(color2);
      }
      if (fillCheckbox.isSelected()) { 
	previewShape.setFilled(true);
	solidButton.setEnabled(true);
	linearButton.setEnabled(true);
	radialButton.setEnabled(true);
	transPanel.setVisible(true);
	if (solidButton.isSelected()) { 
	  centerPanelLayout.show(middlePanel, "solid");
	  colorButton1.setVisible(true);
	  colorButton2.setVisible(false);
	  swapButton.setVisible(false);
	  //colorPanelBorder.setTitle(getResourceString("SelectFillColor.text"));
	  //middlePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
	  colorPanelLabel.setText(getResourceString("SelectFillColor.text"));
	  colorPanel.setBorder(BorderFactory.createEtchedBorder());
	  middlePanelLabel.setText("");
	  middlePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
	} else if (linearButton.isSelected()) { 
	  centerPanelLayout.show(middlePanel, "linear");
	  colorButton1.setVisible(true);
	  colorButton2.setVisible(true);
	  swapButton.setVisible(true);
	  /*
	  colorPanelBorder.setTitle(getResourceString("SelectGradientColors.text"));
	  middlePanelBorder.setTitle(getResourceString("Gradient.Pattern.text"));
	  middlePanel.setBorder(BorderFactory.createCompoundBorder(middlePanelBorder, 
								   BorderFactory.createEmptyBorder(5, 5, 5, 5)));
	  */
	  colorPanelLabel.setText(getResourceString("SelectGradientColors.text"));
	  colorPanel.setBorder(BorderFactory.createEtchedBorder());
	  middlePanelLabel.setText(getResourceString("Gradient.Pattern.text"));
	  middlePanel.setBorder(BorderFactory.createEtchedBorder());
	} else { 
	  centerPanelLayout.show(middlePanel, "radial");
	  colorButton1.setVisible(true);
	  colorButton2.setVisible(true);
	  swapButton.setVisible(true);
	  /*
	  colorPanelBorder.setTitle(getResourceString("SelectGradientColors.text"));
	  middlePanelBorder.setTitle(getResourceString("Gradient.Pattern.text"));
	  middlePanel.setBorder(BorderFactory.createCompoundBorder(middlePanelBorder, 
								 BorderFactory.createEmptyBorder(5, 5, 5, 5)));
	  */
	  colorPanelLabel.setText(getResourceString("SelectGradientColors.text"));
	  colorPanel.setBorder(BorderFactory.createEtchedBorder());
	  middlePanelLabel.setText(getResourceString("Gradient.Pattern.text"));
	  middlePanel.setBorder(BorderFactory.createEtchedBorder());
	}
	//colorPanel.setBorder(BorderFactory.createCompoundBorder(colorPanelBorder, 
	//BorderFactory.createEmptyBorder(5, 5, 5, 5)));
      } else {       
	previewShape.setFilled(false);
	solidButton.setEnabled(false);
	linearButton.setEnabled(false);
	radialButton.setEnabled(false);
	// disable center and right panel
	centerPanelLayout.show(middlePanel, "solid");
	colorButton1.setVisible(false);
	colorButton2.setVisible(false);
	swapButton.setVisible(false);
	colorPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
	middlePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
	colorPanelLabel.setText("");
	middlePanelLabel.setText("");
	transPanel.setVisible(false);
      }
      previewPanel.updatePreview();
      updateGradientPanels();
      doLayout();
    }
    
    protected void updateGradientPanels() { 
      boolean filled = fillCheckbox.isSelected();
      boolean solid = solidButton.isSelected();
      Color color1 = colorIcon1.getColor();
      Color color2 = colorIcon2.getColor();
      int a = transPanel.getValue();
      if (a < 255) {
	color1 = new Color(color1.getRed(), color1.getGreen(), color1.getBlue(), a);
	color2 = new Color(color2.getRed(), color2.getGreen(), color2.getBlue(), a);
      }
      gradientPanels[1].setAttribute(filled, solid, color1, color2);
      gradientPanels[2].setAttribute(filled, solid, color1, color2);
    }

    protected DrawApp main;
    
    // states
    protected static final int NO_FILL = 0;
    protected static final int FILL_SOLID = 1;
    protected static final int FILL_LINEAR_GRADIENT = 2;
    protected static final int FILL_RADIAL_GRADIENT = 3;

    protected int curState = NO_FILL;
    
    protected Color color1 = new Color(148, 255, 94); //Color.lightGray;
    protected Color color2 = new Color(100, 200, 255);
    protected ColoredSquare colorIcon1, colorIcon2; 
    protected JButton colorButton1, colorButton2; 
    protected JButton swapButton; 
    
    protected JPanel leftPanel;
    protected JCheckBox fillCheckbox; 
    protected JRadioButton solidButton, linearButton, radialButton;
    
    protected JPanel topPanel;
    protected JPanel centerPanel;
    protected JPanel colorPanel;  
    protected JPanel middlePanel;
    
    //protected TitledBorder colorPanelBorder; 
    //protected TitledBorder middlePanelBorder; 
    protected JLabel colorPanelLabel; 
    protected JLabel middlePanelLabel; 
    
    protected GPanel[] gradientPanels = new GPanel[3]; 
    protected PreviewPanel previewPanel;
    protected CardLayout centerPanelLayout; 
    
    protected TransparencyPanel transPanel;
    
  }

}

class PreviewPanel extends JPanel { 

  PreviewPanel() { 
    Border border;
    /*
    border = BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), 
					      " " + getResourceString("GradientPreview.text") + " ",
					      TitledBorder.CENTER, TitledBorder.TOP,
					      titleFont, Color.BLACK);
    border = BorderFactory.createCompoundBorder(border, 
						BorderFactory.createEmptyBorder(5, 5, 5, 5));
    */

    border = BorderFactory.createEtchedBorder();
    setBorder(border);
    setLayout(new BorderLayout());
    JLabel title = new JLabel(getResourceString("GradientPreview.text")); 
    title.setHorizontalAlignment(SwingConstants.CENTER);
    add(title, BorderLayout.NORTH);
    //ShapeIcon icon = new ShapeIcon(new RectangleShape(0, 0, 100, 80), 100, 80);
    FillIcon icon = new FillIcon(100, 80);
    previewShape = icon.getDrawShape();
    attr = icon.getDrawAttr();
    preview = new JLabel(icon); 
    add(preview, BorderLayout.CENTER);
  }

  public DrawAttr getDrawAttr() { 
    return attr;
  }

  public DrawShape getDrawShape() { 
    return previewShape; 
  }

  public void updatePreview() { 
    //System.out.println("PreviewPanel.updatePreview()");
    //preview.invalidate();
    preview.repaint();
  }

  protected JLabel preview; 
  protected DrawShape previewShape; 
  protected DrawAttr attr;

}

class GPanel extends JPanel { 

  GPanel() { 
    setPreferredSize(new Dimension(150, 50)); 
  }

  public void setAttribute(boolean filled, boolean solid, Color c1, Color c2) { 
    if (buttons != null) { 
      for (int i = 0; i < buttons.length; i++) { 
	buttons[i].shape.setFilled(filled);
	if (solid) { 
	  buttons[i].attr.setGradientColor1(null);
	  buttons[i].attr.setGradientColor2(null);
	} else { 
	  buttons[i].attr.setGradientColor1(c1);
	  buttons[i].attr.setGradientColor2(c2);
	}      
	buttons[i].repaint();
      }
    }
  }

  protected GradientButton[] buttons;

}

class LinearGradientPanel extends GPanel { 

  LinearGradientPanel(ActionListener act) { 
    setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    setLayout(new GridLayout(2, 4));
    buttons = new GradientButton[8];
    ButtonGroup group = new ButtonGroup();
    for (int i = 0; i < 8; i++) { 
      buttons[i] = new GradientButton();
      group.add(buttons[i]);
      add(buttons[i]);
      buttons[i].attr.setGradientMode(gradientModes[i % 4]);
      buttons[i].attr.setGradientReflect(i >= 4);
      if (act != null) { 
	buttons[i].addActionListener(act);
      }
    }    
  }

  static final int[] gradientModes = {  
    DrawAttr.LINEAR_GRADIENT_LEFT_TO_RIGHT,
    DrawAttr.LINEAR_GRADIENT_TOP_TO_BOTTOM,
    DrawAttr.LINEAR_GRADIENT_DIAGNAL_DOWN,
    DrawAttr.LINEAR_GRADIENT_DIAGNAL_UP,
  };

}

class GradientButton extends JToggleButton {

  GradientButton() { 
    //icon = new ShapeIcon(new RectangleShape(0, 0, 30, 20), 30, 20);
    icon = new FillIcon(30, 20);    
    shape = icon.getDrawShape();
    shape.setFilled(true);
    attr = icon.getDrawAttr();    
    setIcon(icon);
  }

  DrawShape shape;
  DrawAttr attr;
  FillIcon icon;

}


class RadialGradientPanel extends GPanel { 

  RadialGradientPanel(ActionListener act) { 
    setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    setLayout(new GridLayout(2,4));
    buttons = new GradientButton[5];
    ButtonGroup group = new ButtonGroup();
    for (int i = 0; i < 5; i++) { 
      buttons[i] = new GradientButton();
      group.add(buttons[i]);
      add(buttons[i]);
      buttons[i].attr.setGradientMode(gradientModes[i]);
      buttons[i].attr.setGradientReflect(false);
      if (act != null) { 
	buttons[i].addActionListener(act);
      }
    }   
    //add(Box.createRigidArea(new Dimension(10, 15)));
  }

  static final int[] gradientModes = {
    DrawAttr.RADIAL_GRADIENT_CENTER,
    DrawAttr.RADIAL_GRADIENT_UPPER_LEFT,
    DrawAttr.RADIAL_GRADIENT_UPPER_RIGHT,
    DrawAttr.RADIAL_GRADIENT_LOWER_LEFT, 
    DrawAttr.RADIAL_GRADIENT_LOWER_RIGHT,
  };
}
